package cn.yuanqiao.web.controller.archive.bianjifabu;

import cn.yuanqiao.archive.appManager.domain.TenantCategory;
import cn.yuanqiao.archive.appManager.domain.TenantYqdaDocument;
import cn.yuanqiao.archive.appManager.mapper.TenantCategoryMapper;
import cn.yuanqiao.archive.appManager.mapper.TenantYqdaDocumentMapper;
import cn.yuanqiao.archive.bianjifabu.domain.Yqfabufangan;
import cn.yuanqiao.archive.bianjifabu.domain.YqfabufanganDa;
import cn.yuanqiao.archive.bianjifabu.domain.Yqfanganwater;
import cn.yuanqiao.archive.bianjifabu.service.IYqfabufanganService;
import cn.yuanqiao.archive.bianjifabu.util.PdfUtils;
import cn.yuanqiao.archive.utils.FileWaterMark;
import cn.yuanqiao.archive.wenjianzhengli.domain.Yqdatransdoc;
import cn.yuanqiao.common.core.domain.AjaxResult;
import cn.yuanqiao.common.exception.ServiceException;
import cn.yuanqiao.common.utils.DESUtil;
import cn.yuanqiao.common.utils.SecurityUtils;
import cn.yuanqiao.common.utils.StringUtils;
import cn.yuanqiao.common.utils.poi.ExcelUtil;
import cn.yuanqiao.common.web.controller.BaseController;
import cn.yuanqiao.common.web.page.TableDataInfo;
import cn.yuanqiao.common.annotation.Log;
import cn.yuanqiao.common.enums.BusinessType;

import cn.yuanqiao.common.core.context.ResponseUtils;
import com.alibaba.fastjson.JSONObject;
import org.mozilla.universalchardet.UniversalDetector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 发布方案Controller
 *
 * @author yuanqiao
 * @date 2024-03-18
 */
@RestController
@RequestMapping("/archive/yqfabufangan")
public class YqfabufanganController extends BaseController
{
    @Autowired
    private IYqfabufanganService YqfabufanganService;
    @Autowired
    private TenantYqdaDocumentMapper documentMapper;
    @Autowired
    private TenantCategoryMapper tenantCategoryMapper;

    /**
     * 查询发布方案列表
     */
    //@RequiresPermissions("archiveYQFABUFANGAN:list")
    @GetMapping("/list")
    public TableDataInfo list(Yqfabufangan Yqfabufangan)
    {
        startPage();
        List<Yqfabufangan> list = YqfabufanganService.selectYqfabufanganList(Yqfabufangan);
        return getDataTable(list);
    }

    @PostMapping("/daList")
    public TableDataInfo daList(@RequestBody JSONObject json)
    {
        startPage();
        List<Map<String,Object>> list = YqfabufanganService.selectDaList(json);
        return getDataTable(list);
    }
    @GetMapping("/showColumns")
    public TableDataInfo showColumns(@RequestParam("subTableName") String subTableName,@RequestParam("type") String type)
    {
        //startPage();
        List<Map<String,Object>> list = YqfabufanganService.showColumnsByCateID(subTableName,type);
        return getDataTable(list);
    }

    @GetMapping("/getFileList")
    public TableDataInfo getFileList(@RequestParam("fanganId") String fanganId,@RequestParam("subTableName") String subTableName)
    {
        //startPage();
        List<Map<String,Object>> list = YqfabufanganService.getFileList(fanganId,subTableName);
        return getDataTable(list);
    }

    @GetMapping("/selectDataOfFangan")
    public TableDataInfo selectDataOfFangan(@RequestParam("fanganId")String fanganId)
    {
        startPage();
        List<YqfabufanganDa> list = YqfabufanganService.selectDataOfFangan(fanganId);
        return getDataTable(list);
    }
    @GetMapping("/kfjdList")
    public TableDataInfo kfjdList(@RequestParam("subTableName")String subTableName)
    {
        //startPage();
        List<Map<String,Object>> list = YqfabufanganService.kfjdList(subTableName);
        return getDataTable(list);
    }

    @PostMapping("/addDaToFangan")
    public AjaxResult addDaToFangan(@RequestBody JSONObject json)
    {
        int i = YqfabufanganService.addDaToFangan(json);
        if(i==999){
            return  AjaxResult.warn("请勿重复添加档案条目!");
        }
        return toAjax(i);
    }

    @PostMapping("/addJianDingJobDa")
    public AjaxResult addJianDingJobDa(@RequestBody JSONObject json)
    {
        return toAjax(YqfabufanganService.addJianDingJobDa(json));
    }

    @PostMapping("/addAllDaToFangan")
    public AjaxResult addAllDaToFangan(@RequestBody JSONObject json)
    {
        return toAjax(YqfabufanganService.addAllDaToFangan(json));
    }

    /**
     * 导出发布方案列表
     */
    //@RequiresPermissions("archiveYQFABUFANGAN:export")
    @Log(title = "发布方案", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Yqfabufangan Yqfabufangan)
    {
        List<Yqfabufangan> list = YqfabufanganService.selectYqfabufanganList(Yqfabufangan);
        ExcelUtil<Yqfabufangan> util = new ExcelUtil<Yqfabufangan>(Yqfabufangan.class);
        util.exportExcel(response, list, "发布方案数据");
    }

    @PostMapping("/downLoadXml")
    public void downLoadXml(HttpServletResponse response, @RequestParam("data") String data)
    {
        JSONObject json = JSONObject.parseObject(data);
        File file = YqfabufanganService.downLoadXml(json);
        try {
            // 获取文件名
            String filename = file.getName();
            // 将文件写入输入流
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStream fis = new BufferedInputStream(fileInputStream);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置 CORS 响应头
            ResponseUtils.defaultResponse(response);
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
            // 告知浏览器文件的大小
            response.addHeader("Content-Length", "" + file.length());
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            outputStream.write(buffer);
            outputStream.flush();
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    /**
     * 获取发布方案详细信息
     */
    //@RequiresPermissions("archiveYQFABUFANGAN:query")
    @GetMapping(value = "/{ID}")
    public AjaxResult getInfo(@PathVariable("ID") String ID)
    {
        Yqfabufangan yqfabufangan = YqfabufanganService.selectYqfabufanganByID(ID);
        return success(yqfabufangan);
    }

    @GetMapping("/selectWater")
    public AjaxResult selectWater(@RequestParam("fanganId") String fanganId)
    {
        return success(YqfabufanganService.selectYqfanganwaterList(fanganId));
    }

    /**
     * 新增发布方案
     */
    //@RequiresPermissions("archiveYQFABUFANGAN:add")
    @Log(title = "发布方案", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Yqfabufangan Yqfabufangan)
    {
        return toAjax(YqfabufanganService.insertYqfabufangan(Yqfabufangan));
    }

    /**
     * 修改发布方案
     */
    //@RequiresPermissions("archiveYQFABUFANGAN:edit")
    @Log(title = "发布方案", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Yqfabufangan Yqfabufangan)
    {
        return toAjax(YqfabufanganService.updateYqfabufangan(Yqfabufangan));
    }

    /**
     * 删除发布方案
     */
    //@RequiresPermissions("archiveYQFABUFANGAN:remove")
    @Log(title = "删除方案中档案", businessType = BusinessType.DELETE)
	@DeleteMapping
    public AjaxResult remove(@RequestParam("daId") String ID,@RequestParam("fanganId") String fanganId)
    {
        return toAjax(YqfabufanganService.deleteYqfabufanganByIDs(ID,fanganId));
    }

    /**
     * 修改方案审批状态
     * @param fanganId
     * @param state
     * @return
     */
	@PutMapping("/updateState")
    public AjaxResult updateState(@RequestParam("fanganId") String fanganId,@RequestParam("state")String state)
    {
        return toAjax(YqfabufanganService.updateState(fanganId,state));
    }


    @PutMapping("/submitBjfb")
    public AjaxResult submitBjfb(@RequestParam("fanganId") String fanganId)
    {
        return toAjax(YqfabufanganService.submitBjfb(fanganId));
    }


    //@RequiresPermissions("manage:YQFANGANWATER:add")
    //@Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT)
    @PostMapping("/addFangAnWater")
    public AjaxResult addFangAnWater(@RequestBody Yqfanganwater Yqfanganwater)
    {
        return toAjax(YqfabufanganService.insertYqfanganwater(Yqfanganwater));
    }

    @PostMapping("/publishOnLine")
    public void publishOnLine(@RequestBody JSONObject jsonObject){
        YqfabufanganService.publishOnLine(jsonObject);
    }

    @PostMapping("/cancelPublish")
    public AjaxResult cancelPublish(@RequestParam("fanganId")String fanganId,
                              @RequestParam("subTableName")String subTableName){
        int i = YqfabufanganService.cancelPublish(fanganId, subTableName);
        return toAjax(i);
    }

    @PostMapping("/view")
    public void view(HttpServletResponse response,@RequestParam("docId")String docId,
                     @RequestParam("subTableName")String subTableName,@RequestParam("fanganId")String fanganId) throws Exception {
        if(StringUtils.isEmpty(docId) || "null".equals(docId)){
            throw new ServiceException("docId不能为空");
        }
        if(StringUtils.isEmpty(subTableName) || "null".equals(subTableName)){
            throw new ServiceException("subTableName不能为空");
        }
        if(StringUtils.isEmpty(fanganId) || "null".equals(fanganId)){
            throw new ServiceException("fanganId不能为空");
        }
        TenantCategory tenantCategory = tenantCategoryMapper.selectTenantCategoryByTableName(subTableName, new TenantCategory().getTableName());
        TenantYqdaDocument document = documentMapper.selectnameandpathbyDocid(Long.valueOf(docId),tenantCategory.getEfileTableName());
        String url = document.getDocMnt() + document.getPath();
        if("pdf".equalsIgnoreCase(document.getDocFileType())){
            Boolean aBoolean = FileWaterMark.PdfIsEncryption(url);
            if(!aBoolean){
                List<Yqfanganwater> yqfanganwaters = YqfabufanganService.selectYqfanganwaterList(fanganId);
                if(null!=yqfanganwaters && yqfanganwaters.size()>0){
                    Yqfanganwater yqfanganwater = yqfanganwaters.get(0);
                    String path = document.getPath();
                    String separator = File.separator;
                    if(separator.equals("\\")){
                        separator = "\\\\";
                    }
                    String[] pathArr = path.split(separator);
                    String[] nameArr = pathArr[pathArr.length-1].split("\\.");
                    String newpath = path.substring(0,path.lastIndexOf(File.separator));
                    newpath+=File.separator+nameArr[0]+"-fabuwater."+nameArr[1];
                    //String fabuwaterfontposition = sysConfigService.selectConfigByKey("FABUWATERFONTPOSITION");
                    PdfUtils.PDFAddWatermark(document.getDocMnt()+path, document.getDocMnt()+newpath, yqfanganwater);
                    url = document.getDocMnt()+newpath;
                }
            }
        }

        logger.info(url);
        if (url.equals("null")) {
            response.sendError(404, "File not found!");
            return;
        }
        response.reset(); // 非常重要
        // 设置 CORS 响应头
        ResponseUtils.defaultResponse(response);
        if ("TXT".equalsIgnoreCase(document.getDocFileType())) {
            readTxtFile(url, document.getDocName(), response);
        } else {
            //在线预览，浏览器支持的文件类型都能打开
            URL u = new URL("file:///" + url);
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(document.getDocName(),"UTF-8") + "\"");
            FileInputStream inputStream = null;

            inputStream = new FileInputStream(url);
            int len = 0;
            byte[] buf = new byte[4096];
            OutputStream out = response.getOutputStream();
            while ((len = inputStream.read(buf)) > 0) {
                out.write(buf, 0, len);
                out.flush(); // 定期刷新输出流
            }
            System.gc();
            inputStream.close();
            out.close();
        }

    }
    @PostMapping("/getOfdFile")
    public AjaxResult getOfdFile(@RequestParam("docId")String docId,
                                 @RequestParam("subTableName")String subTableName,@RequestParam("fanganId")String fanganId) throws Exception {
        if(StringUtils.isEmpty(docId) || "null".equals(docId)){
            throw new ServiceException("docId不能为空");
        }
        if(StringUtils.isEmpty(subTableName) || "null".equals(subTableName)){
            throw new ServiceException("subTableName不能为空");
        }
        if(StringUtils.isEmpty(fanganId) || "null".equals(fanganId)){
            throw new ServiceException("fanganId不能为空");
        }
        TenantCategory tenantCategory1 = new TenantCategory();
        String catetablename = tenantCategory1.getTableName();
        TenantCategory tenantCategory = tenantCategoryMapper.selectTenantCategoryByTableName(subTableName, catetablename);

        //TenantYqda tenantYqda = new TenantYqda();
        //String allftable = tenantYqda.getTableName();
        String efiletable = tenantCategory.getEfileTableName();
       /* if (null == daId || "null".equals(daId)) {
            //tenantCategory.setCategoryId(Long.parseLong(categoryId));
            TenantCategory tenantCategory1 = categoryMapper.selectTenantCategoryByID(Long.parseLong(categoryId), new TenantCategory().getTableName());
            efiletable = tenantCategory1.getEfileTableName();
        } else {
            efiletable = documentMapper.gettablenamebydaid(Long.parseLong(daId), allftable, catetablename);
        }*/
        TenantYqdaDocument document = documentMapper.viewByDocid(Long.valueOf(docId), efiletable, new Yqdatransdoc().getTableName());
        String url = document.getDocMnt() + File.separator + document.getPath();
        File file = new File(url);
        if (!file.exists()) {
            return AjaxResult.error(404, "File not found!");
        } else {
            JSONObject object = new JSONObject();
            object.put("time", String.valueOf(new Date().getTime()));
            object.put("tenantCode", SecurityUtils.getTenantCode());
            object.put("path", file.getAbsolutePath());
            object.put("userId", SecurityUtils.getUserId());
            String msg = object.toJSONString();
            logger.info(msg);
            msg = DESUtil.encrypt(msg);
            return AjaxResult.success(Base64Utils.encodeToUrlSafeString(msg.getBytes()));
        }
    }
    private void readTxtFile(String filePath, String fileName, HttpServletResponse response) {
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath))) {
            UniversalDetector detector = new UniversalDetector(null);
            byte[] buf = new byte[4096];
            int nread;

            while ((nread = bis.read(buf)) > 0 && !detector.isDone()) {
                detector.handleData(buf, 0, nread);
            }

            detector.dataEnd();
            //读取txt文件的编码格式
            String encoding = detector.getDetectedCharset();
            detector.reset();
            //以确定的编码格式读取文件
            OutputStream out = response.getOutputStream();
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), encoding))) {
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    sb.append(line);
                    sb.append(System.lineSeparator());
                }
                String fileContent = sb.toString();
                // 之后你可以将fileContent作为你的响应内容
                response.setContentType("text/plain; charset=" + encoding); // 设置正确的编码格式
                response.setHeader("Content-Disposition", "inline; filename=\"" + fileName + "\"");
                out.write(fileContent.getBytes(encoding));
            }
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
